/**
 * 
 */
package cn.nawang.ebeim.api.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;

import cn.nawang.ebeim.api.bean.DatasourceBean;
import cn.nawang.ebeim.api.bean.DatasourceMenuBean;
import cn.nawang.ebeim.api.comm.PageList;
import cn.nawang.ebeim.api.comm.Pages;
import cn.nawang.ebeim.api.domain.BackStrategy;
import cn.nawang.ebeim.api.domain.Datasource;
import cn.nawang.ebeim.api.domain.DatasourceConfig;
import cn.nawang.ebeim.api.domain.User;
import cn.nawang.ebeim.api.repository.BackStrategyRepository;
import cn.nawang.ebeim.api.repository.DatasourceConfigRepository;
import cn.nawang.ebeim.api.repository.DatasourceRepository;
import cn.nawang.ebeim.api.repository.UserRepository;
import cn.nawang.ebeim.api.repository.impl.DatasourceConfigQueryRepositoryImpl;
import cn.nawang.ebeim.api.repository.impl.DatasourceQueryRepositoryImpl;
import cn.nawang.ebeim.api.service.DatasourceConfigService;
import cn.nawang.ebeim.api.service.DatasourceService;
import cn.nawang.ebeim.api.utils.Constant;
import cn.nawang.ebeim.api.utils.Util;
import cn.nawang.ebeim.api.vo.DatasourceView;

/**
 * @ClassName: DatasourceServiceImpl
 * @Description: 数据源业务逻辑实现层
 * @author 张建峰
 * @date 2015年8月11日 上午11:55:56
 * @version v1.0
 */
@Service("datasourceService")
public class DatasourceServiceImpl implements DatasourceService {

  @Autowired
  DatasourceRepository datasourceRepository;
  @Autowired
  UserRepository userRepository;
  @Autowired
  BackStrategyRepository backStrategyRepository;
  @Autowired
  DatasourceQueryRepositoryImpl datasourceQueryRepositoryImpl;
  @Autowired
  private DatasourceConfigService datasourceConfigService;
  @Autowired
  DatasourceConfigQueryRepositoryImpl datasourceConfigQueryRepositoryImpl;

  @Autowired
  private DatasourceConfigRepository datasourceConfigRepository;


  /**
   * @author 张建峰
   * @Description: 保存
   * @param @param datasource
   * @date 2015年8月7日上午8:34:31
   *
   * @修改人 张建峰
   * @修改日期
   */
  @Override
  public void save(Datasource datasource) {
    datasource.setCreateTime(new Date().getTime());
    datasource.setLmTime(new Date().getTime());
    datasourceRepository.save(datasource);
  }

  /**
   * @author 张建峰
   * @Description: 根据id查询
   * @param @param id
   * @param @return
   * @date 2015年8月7日上午8:34:45
   *
   * @修改人 张建峰
   * @修改日期
   */
  @Override
  public DatasourceBean findOne(String id) {
    DatasourceBean bean = new DatasourceBean();
    Datasource datasource = datasourceRepository.findOne(id);
    if (datasource == null) {
      return null;
    } else {
      BeanUtils.copyProperties(datasource, bean);
      User user = userRepository.findOne(datasource.getCreateUserId());
      BackStrategy strategy = backStrategyRepository.findByDatasourceId(datasource.getId());
      bean.setCreateUserName(user.getName());
      BeanUtils.copyProperties(strategy, bean);
      bean.setBackupStrategyId(strategy.getBsId());
      List<DatasourceConfig> dsConfigs =
          datasourceConfigQueryRepositoryImpl.findByParam("configId", datasource.getConfigId());
      if (dsConfigs != null && dsConfigs.size() > 0) {
        DatasourceConfig dsConfig = dsConfigs.get(0);
        BeanUtils.copyProperties(dsConfig, bean);
      }
      bean.setId(datasource.getId());
    }
    return bean;
  }

  /**
   * @author 张建峰
   * @Description: 分页查询
   * @param @param t
   * @param @param page
   * @param @return
   * @return PageList
   * @date 2015年8月7日上午9:58:17
   *
   * @修改人 张建峰
   * @修改日期
   */
  public PageList findByDatasource(Datasource obj, Pages page) {
    return datasourceQueryRepositoryImpl.findByDatasource(obj, page);
  }

  /**
   * @author 张建峰
   * @Description: 根据id获取DatasourceBean
   * @param @param id
   * @param @return
   * @date 2015年9月9日下午5:35:52
   *
   * @修改人 张建峰
   * @修改日期
   */
  @Override
  public DatasourceBean findDatasourceBean(String id) {
    String param = "id";
    List<DatasourceView> list = datasourceQueryRepositoryImpl.findDatasourceViewByParam(param, id);
    if (!list.isEmpty() && list != null) {
      DatasourceBean bean = new DatasourceBean();
      DatasourceView view = list.get(0);
      // 设置新增用户名称
      User user = userRepository.findOne(view.getCreateUserId());
      bean.setCreateUserName(user.getName());
      BeanUtils.copyProperties(view, bean);
      return bean;
    }
    return null;
  }

  @Override
  public Datasource findDatasource(String id) {
    return datasourceRepository.findOne(id);
  }

  @Override
  public DatasourceView findDatasourceView(String id) {
    String param = "id";
    List<DatasourceView> list = datasourceQueryRepositoryImpl.findDatasourceViewByParam(param, id);
    if (!list.isEmpty() && list != null) {
      return list.get(0);
    }
    return null;
  }

  @Override
  public boolean updateDatasource(Datasource datasource, DatasourceConfig datasouceConfig,
      BackStrategy bs, User user) {

    try {
      Datasource datasourceByDatabase = findDatasource(datasource.getId());
      datasource.setLmTime(new Date().getTime());
      if (user != null) {
        datasource.setLmUserId(user.getId());
      }
      datasource = (Datasource) Util.comparisonObject(datasource, datasourceByDatabase);
      datasourceRepository.save(datasource);

      if (datasouceConfig != null) {
        DatasourceConfig datasourceConfigByDatabase =
            datasourceConfigRepository.findOne(datasourceByDatabase.getConfigId());
        datasouceConfig =
            (DatasourceConfig) Util.comparisonObject(datasouceConfig, datasourceConfigByDatabase);
        datasourceConfigRepository.save(datasouceConfig);
      }

      if (bs != null) {

        BackStrategy bsByDatabase = backStrategyRepository.findByDatasourceId(datasource.getId());
        bs.setBsId(bsByDatabase.getBsId());
        if (bs.getBackupTime() != null && bs.getBackupTime() != bsByDatabase.getBackupTime()) {
          bs.setBackupTimeStatus(Integer.valueOf(Constant.BACKUP_TIME_STATUS_ONE));
        }
        bs = (BackStrategy) Util.comparisonObject(bs, bsByDatabase);
        backStrategyRepository.save(bs);
      }

      return true;
    } catch (Throwable e) {
      e.printStackTrace();
    }
    return false;
  }

  @Override
  public List<DatasourceView> findDatasourceViewByParam(String property, Object value) {
    return datasourceQueryRepositoryImpl.findDatasourceViewByParam(property, value);
  }

  /**
   * @author zhangjf
   * @Description: 分页查询
   * @param @param property
   * @param @param value
   * @param @param currPage
   * @param @param pageSize
   * @param @return
   * @return JSONObject
   * @date 2015年10月12日下午3:08:00
   *
   * @修改人 zhangjf
   * @修改日期
   */
  public JSONObject findDatasourceViewByPage(String property, Object value, Integer currPage,
      Integer pageSize) {
    return datasourceQueryRepositoryImpl.findDatasourceViewByPage(property, value, currPage,
        pageSize);
  }

  @Override
  public boolean add(Datasource datasource) {
    try {
      datasourceRepository.save(datasource);
      return true;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return false;
  }

  @Override
  public JSONObject addDatasource(Datasource datasource, DatasourceConfig datasourceConfig,
      BackStrategy bs, User user) {

    JSONObject json = new JSONObject();
    
    if (bs.getBackupTime() == null
        && !datasource.getDsType().equals(Constant.DATESOURCE_TYPE_TWO)) {
      bs.setBackupTime(new Date().getTime());
    }


    try {
      datasourceConfig.setConfigId("DC-" + new Date().getTime() + "-" + new Random().nextInt(1000));
      datasourceConfigRepository.save(datasourceConfig);

      datasource.setId("DS-" + new Date().getTime() + "-" + new Random().nextInt(1000));
      json.put("dsId", datasource.getId());
      datasource.setConfigId(datasourceConfig.getConfigId());
      datasource.setCreateUserId(user.getId());
      datasource.setCustomerId(user.getCustomerId());
      datasource.setCreateTime(new Date().getTime());
      datasource.setStatus(Constant.DATESOURCE_RUN_STATUS_TYPE_ZERO);
      datasource.setDsStatus(Constant.DATESOURCE_DS_STATUS_TYPE_ZERO);
      datasource.setNextRun(bs.getBackupTime());
      datasourceRepository.save(datasource);

      bs.setBsId("BS-" + new Date().getTime() + "-" + new Random().nextInt(1000));
      bs.setBackupTimeStatus(Integer.valueOf(Constant.BACKUP_TIME_STATUS_ONE));
      bs.setDatasourceId(datasource.getId());
      backStrategyRepository.save(bs);
      json.put("code", Constant.CODE_SUCCESS);
      return json;
    } catch (Exception e) {
      e.printStackTrace();
    }
    json.put("code", Constant.CODE_ERROR);
    return json;
  }

  @Override
  public boolean delete(Datasource datasource) {
    try {
      datasourceRepository.delete(datasource);
      return true;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return false;
  }

  @Override
  public PageList findAllByPaging(Pages page) {
    return datasourceQueryRepositoryImpl.findAllByPaging(page);
  }

  @Override
  public Datasource findByDeviceAndRoot(String terminalId, String root ,String createUserId) {
    return datasourceQueryRepositoryImpl.findByDeviceAndRoot(terminalId, root,createUserId);
  }

  @Override
  public List<DatasourceMenuBean> findBindDeviceNameByTerminalId(String createUserId) {
    return datasourceQueryRepositoryImpl.findBindDeviceNameByTerminalId(createUserId);
  }

  @Override
  public List findListByUserId(String mac, String userId) {
    return datasourceQueryRepositoryImpl.findListByUserId(mac, userId);
  }

  @Override
  public Map findSafeBoxByUserId(String mac, String userId) {
    return datasourceQueryRepositoryImpl.findSafeBoxByUserId(mac, userId);
  }

  @Override
  public List findPlanListByUserId(String mac, String userId, String useSel) {
    return datasourceQueryRepositoryImpl.findPlanListByUserId(mac, userId, useSel);
  }

  @Override
  public int countByUserId(String userId, String terminalId, String status, String dsType) {
    return datasourceQueryRepositoryImpl.countByUserId(userId, terminalId, status, dsType);
  }

  @Override
  public boolean updateDatasourcesStatus(String[] ids, int dsStatus) {
    return datasourceQueryRepositoryImpl.updateDatasourcesStatus(ids, dsStatus);
  }

  @Override
  public List<Datasource> findDatasources(String[] ids, int status) {
    return datasourceQueryRepositoryImpl.findDatasources(ids, status);
  }

  @Override
  public List<Datasource> findByCreateUserIdAndDsType(String createUserId, String dsType) {
    return datasourceQueryRepositoryImpl.findByCreateUserIdAndDsType(createUserId, dsType);
  }

}
